package io.gitee.yanbinchen;


import org.aopalliance.intercept.MethodInterceptor;
import org.aopalliance.intercept.MethodInvocation;

import java.lang.reflect.Method;

/**
 * @author: alex
 * @since : 2025-02-28 21:32
 */
public class SuperCacheInterceptor implements MethodInterceptor {

    @Override
    public Object invoke(MethodInvocation invocation) throws Throwable {
        String name = invocation.getThis().getClass().getName();
        Method method = invocation.getMethod();
        Object[] args = invocation.getArguments();
        MetaInfo metaInfo = new MetaInfo(name, method.getName(), method.getParameters(), null, null);
        SuperKey superKey = CacheContextHolder.get(metaInfo.getMetaId());
        DelSuperKey delSuperKey = CacheContextHolder.getDel(metaInfo.getMetaId());
        if (delSuperKey != null && superKey != null) {
            String delKey = getCacheKey(delSuperKey, method, args);
            CacheContextHolder.getSuperCacheService().unlink(delKey);
            String key = getCacheKey(superKey, method, args);
            Object value = CacheContextHolder.getSuperCacheService().getCache(key, superKey.clzName(), superKey);
            if (StrUtils.isNotEmpty(value)) {
                return value;
            }
            Object res = invocation.proceed();
            if (StrUtils.isNotEmpty(res)) {
                CacheContextHolder.getSuperCacheService().setCache(key, res, superKey);
            }
            return res;
        } else if (delSuperKey != null) {
            String delKey = getCacheKey(delSuperKey, method, args);
            CacheContextHolder.getSuperCacheService().unlink(delKey);
            return invocation.proceed();
        } else if (superKey != null) {
            String key = getCacheKey(superKey, method, args);
            Object value = CacheContextHolder.getSuperCacheService().getCache(key, superKey.clzName(), superKey);
            if (StrUtils.isNotEmpty(value)) {
                return value;
            }
            Object res = invocation.proceed();
            if (StrUtils.isNotEmpty(res)) {
                CacheContextHolder.getSuperCacheService().setCache(key, res, superKey);
            }
            return res;
        }
        Object res = invocation.proceed();
        return res;
    }

    public String getCacheKey(SuperKey superKey, Method method, Object[] args) {
        if (StrUtils.isNotEmpty(superKey.key())) {
            return superKey.value() + SpelUtils.getKeyByExpression(method, args, superKey.key());
        } else {
            return superKey.value();
        }
    }

    public String getCacheKey(DelSuperKey delSuperKey, Method method, Object[] args) {
        if (StrUtils.isNotEmpty(delSuperKey.key())) {
            return delSuperKey.value() + SpelUtils.getKeyByExpression(method, args, delSuperKey.key());
        } else {
            return delSuperKey.value();
        }
    }
}
